#ifndef LIBTORRENT_PEER_HANDSHAKE_H
#define LIBTORRENT_PEER_HANDSHAKE_H

#include "peer.h"
#include "socket_base.h"
#include <string>

namespace torrent {

class Download;

class PeerHandshake: public SocketBase {
public:
	typedef std::list<PeerHandshake*> Handshakes;

	typedef enum {
		INACTIVE,			// We can't return to being inactive, destroy when closing.
		CONNECTING,
		READ_HEADER,
		WRITE_HEADER,
		READ_ID
	} State;

	PeerHandshake();
	~PeerHandshake();

	static void connect(int fdesc, const std::string dns, unsigned short port);

	virtual void read();
	virtual void write();
	virtual void except();

	virtual int fd();

	Download* download() const { return m_download; }

	static Handshakes& handshakes() { return m_handshakes; }

protected:	// Disable private ctor only warning.
	PeerHandshake(int fdesc, const std::string dns, unsigned short port);

private:

	bool recv1();
	bool recv2();

	static void addConnection(PeerHandshake* p);

	static Handshakes m_handshakes;

	int m_fd;	// Make sure you set this to below zero if you don't want to close it on dtor
	std::string m_infoHash;

	Peer m_peer;
	Peer m_peerOrig;
	Download* m_download;

	// internal state
	State m_state;
	bool m_incoming;

	char* m_buf;
	unsigned int m_pos;
};

} // namespace torrent

#endif // LIBTORRENT_PEER_HANDSHAKE_H
